<template>
    <div v-if="prizeResult && !isSpinning"
        style="position: absolute; top: 40%;transform: translateY(-50%) translateX(-50%);left:50%;" class="card">

        <div class="content">

            <div class="back">
                <div class="back-content">
                    <div class="img">

                        <div class="circle" id="left">
                        </div>
                        <div class="circle" id="right">
                        </div>
                        <div class="circle" id="top">
                        </div>
                        <div class="circle" id="bottom">
                        </div>
                        <div class="circle" id="a">
                        </div>
                        <div class="circle" id="b">
                        </div>
                        <div class="circle" id="c">
                        </div>
                    </div>
                    <strong style="position: absolute;bottom: 0;bottom: 20px; font-size: 18px;">开启海克斯</strong>
                    <div @click="prizeResult = ''" style="position: absolute;right: 10px;font-size: 20px; top: 0px;">x
                    </div>
                </div>
            </div>
            <div class="front"
                style="display: flex;justify-content: space-between;align-items: center;padding: 40px 0;box-sizing: border-box; flex-direction: column;">
                <div @click="prizeResult = ''" style="position: absolute;right: 10px;font-size: 20px; top: 0px;">x</div>
                <img :src="cCard.cover" style="width: 160px;height: 160px;border-radius: 10px;" alt="">
                <div
                    style="width: 100%;height: 50px;display: flex;justify-content: center;align-items: center;font-size: 22px; box-sizing: border-box;padding: 0 10px;">
                    {{ cCard.title }}</div>
                <div style="width: 100%;height: 80px;box-sizing: border-box;padding: 0 10px;">{{ cCard.desc }}
                </div>

            </div>
        </div>
    </div>

    <div class="lottery-container">
        <nut-drag direction="y" :style="{ right: '0px', top: '40px' }">
            <nut-fixed-nav @selected="tselected" v-model:visible="visible" :overlay="false" un-active-text="更多"
                :nav-list="navList" />
        </nut-drag>
        <div v-if="isSpinning" style="position: absolute;top: 60%;transform: scale(250%);" class="loader">
            <div class="box box0">
                <div></div>
            </div>
            <div class="box box1">
                <div></div>
            </div>
            <div class="box box2">
                <div></div>
            </div>
            <div class="box box3">
                <div></div>
            </div>
            <div class="box box4">
                <div></div>
            </div>
            <div class="box box5">
                <div></div>
            </div>
            <div class="box box6">
                <div></div>
            </div>
            <div class="box box7">
                <div></div>
            </div>
            <div class="ground">
                <div></div>
            </div>
        </div>
        <div style="position: absolute;bottom: 40px;">
            <button @click="spin" class="button">{{ spinningText }}</button>
        </div>

    </div>
    <nut-popup v-model:visible="show" round :close-on-click-overlay="false" closeable>
        <div v-if="popType == 1" style="width: 290px;
    height: 454px;">
            <div style="width: 100% ;height: 100%;padding: 20px 24px;box-sizing: border-box; display: flex;flex-direction: column; align-items: center;color: #fff;font-weight: 600;"
                :style="{
                    background: `linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0)),url(${bg})`,
                    backgroundSize: '100% 100%',

                }">

                <div style="color: black;font-size: 22px;">规则</div>
                <div style="margin-top: 30px;">1.游戏开始后，每名玩家轮流抽取卡牌，卡牌任务完成后下一位玩家抽卡。</div>
                <div style="margin-top: 30px;">2.每张卡牌都有特定的任务，玩家完成卡牌上的任务后，轮到下一个玩家操作。</div>
                <div style="margin-top: 30px;">3.可以欠酒、拖酒，但要签认怂书，大家可以尽情享受游戏。</div>
                <div style="margin-top: 30px;">温馨提醒:请勿过量饮酒,祝愿大家玩的开心!!!</div>

            </div>



        </div>
        <div v-if="popType == 2" style="width: 340px;
    height: 554px;">
            <div style="width: 100% ;height: 100%;padding: 20px 10px;box-sizing: border-box; display: flex;flex-direction: column; align-items: center;color: #000;font-weight: 400;"
                :style="{
                    background: `linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0)),url(${bg})`,
                    backgroundSize: '100% 100%',

                }">

                <div style="color: black;font-size: 22px;font-weight: 600;">历史记录</div>
                <div ref="box"
                    style="width: 100%;height: calc(100% - 24px); font-size: 18px; color: #fff; margin-top: 8px;overflow-y: scroll;">

                    <div v-for="e in recordList" style="margin-top: 10px; display: flex;align-items: center;">
                        {{ dayjs(e.time).format('YYYY-MM-DD HH:mm:ss') }} 抽到 <div
                            style="color: gold;margin-left: 8px; font-size: 19px; display: inline-block;"
                            @click="showDetail(e.cardName)">
                            {{ e.cardName }}</div>
                    </div>

                </div>


            </div>



        </div>
        <div v-if="popType == 3" style="width: 340px;
    height: 554px;">
            <div style="width: 100% ;height: 100%;padding: 20px 10px;box-sizing: border-box; display: flex;flex-direction: column; align-items: center;color: #000;font-weight: 400;"
                :style="{
                    background: `linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0)),url(${bg})`,
                    backgroundSize: '100% 100%',

                }">

                <div style="color: black;font-size: 22px;font-weight: 600;">卡牌库存</div>
                <div ref="box"
                    style="width: 100%;height: calc(100% - 24px); font-size: 18px; color: #fff; margin-top: 8px;">
                    <nut-searchbar @change="fuzzySearch" closeable v-model="searchval" background="transparent"
                        placeholder="请输入关键字">

                    </nut-searchbar>
                    <div style="width: 100%;height: calc(100% - 50px);overflow-y: scroll;">
                        <div v-for="e in scardDataBase" style="display: flex;align-items: center;margin-top: 20px;">
                            <img :src="e.cover" style="width: 80px;height: 80px;margin-right: 6px;border-radius: 4px;"
                                alt="">
                            <div
                                style="width: calc(100% - 90px); height: 80px; align-content: space-between;align-items: center;">
                                <div style="font-size: 16px;text-align: center;font-weight: 600">
                                    <span v-html="highlightKeywords(e.title, searchval)"></span>
                                </div>
                                <div style="font-size: 14px;height: calc(100% - 26px);overflow: scroll; ">
                                    <span v-html="highlightKeywords(e.desc, searchval)"></span>
                                </div>
                            </div>
                            <div v-if="!searchval" @click="delCard(e._id)"
                                style="display: flex; padding: 4px;box-sizing: border-box; justify-content: flex-end;width: 20px;height: 20px;background: red;display: flex;align-items: center;justify-content: center;border-radius: 4px;">
                                <CloseLittle color="#fff"></CloseLittle>
                            </div>
                        </div>

                    </div>


                </div>


            </div>



        </div>
        <div v-if="popType == 4" style="width: 340px;
    height: 554px;">
            <div style="width: 100% ;height: 100%;padding: 20px 10px;box-sizing: border-box; display: flex;flex-direction: column; align-items: center;color: #000;font-weight: 400;"
                :style="{
                    background: `linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0)),url(${bg})`,
                    backgroundSize: '100% 100%',

                }">

                <div style="color: black;font-size: 22px;font-weight: 600;">自定义卡牌</div>
                <div ref="box" style="width: 100%;height: calc(100% - 24px);  font-size: 18px; color: #fff;">
                    <nut-form ref="formRef" :model-value="cardConfig" style="width: 100%;height: 100%;" :rules="{

                        title: [
                            { required: true, message: '请填写卡牌名称' },

                        ],
                        desc: [
                            { required: true, message: '请填写描述' },

                        ]
                    }"> <nut-form-item label-position="top" label="卡牌封面">
                            <div
                                style="width: 100%;height: 200px;border: 1px solid #bfbfbf;padding:4px 4px 0 4px; box-sizing: border-box; display: flex;flex-wrap: wrap;align-content: space-between;overflow-y: scroll;">
                                <div @click="currentCardCoverIndex = i" v-for="(e, i) in coverList" :style="{
                                    background: `url(${e}) no-repeat`,
                                    backgroundSize: `100% 100%`,
                                    border: currentCardCoverIndex == i ? `4px solid red` : ``
                                }"
                                    style="width: 50px; height: 50px;margin-left: calc(20% - 50px);  box-sizing: border-box; margin-bottom: 4px;">
                                </div>
                                {{ i }}
                            </div>

                        </nut-form-item>
                        <nut-form-item label="卡牌名称" prop="title">
                            <nut-input clearable v-model="cardConfig.title" placeholder="请输入卡牌名称" type="text"
                                @update:model-value="customBlurValidate('title')" />
                        </nut-form-item>


                        <nut-form-item label="卡牌描述" label-position="top" prop="desc">

                            <nut-textarea @change="customBlurValidate('desc')" placeholder="请输入卡牌描述"
                                v-model="cardConfig.desc" :rows="2" autosize />
                        </nut-form-item>
                        <div
                            style="width: 100%; display: flex; justify-content: space-between;padding: 4px 30px;box-sizing: border-box;">
                            <nut-button @click="addCard" style="width: 120px;" block type="info">新增</nut-button>
                            <nut-button @click="confirmResetCard" style="width: 120px;" block
                                type="default">重置</nut-button>
                        </div>

                    </nut-form>

                </div>


            </div>



        </div>


        <div v-if="popType == 5" style="width: 340px;
    height: 444px;">
            <div style="width: 100% ;height: 100%;padding: 20px 14px;box-sizing: border-box; display: flex;flex-direction: column; align-items: center;color: #000;font-weight: 400;"
                :style="{
                    background: `linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)),url(${bg})`,
                    backgroundSize: '100% 100%',

                }">

                <div style="color: black;font-size: 22px;font-weight: 600;">认怂书</div>
                <div ref="box"
                    style="width: 100%;height: calc(100% - 24px); font-size: 18px; color: #fff; margin-top: 8px;text-align: justify;">
                    本人XXX于2024年10月15日17:36:43
                    在xxx喝酒，因本人自己玩游戏技不如人，划拳划不过喝也喝不过，酒量实在差，真的是喝不下了。我心甘情愿向xxx签下认怂书，承认我是个小酒量!从此喝酒讲话不能大声，别人叫我菜鸟不能还口，必须点头承认，并且回应一声:
                    <div style="font-size: 24px; margin-top: 20px;text-align: center; font-weight: 600;color: yellow;">
                        “我是小酒量!我认怂!”</div>
                    <div style="margin-top: 20px;"> 另:于下次喝酒的时候还清所欠x杯酒。</div>
                    <div style="margin-top: 20px;">见证人:aaa,bbb
                    </div>
                </div>
            </div>
        </div>
    </nut-popup>
</template>

<script setup>
import axios from 'axios';
import { ref, onMounted, getCurrentInstance, computed, watch } from 'vue';
import rule from '../assets/rule.png';
import his from '../assets/his.png';
import base from '../assets/base.png';
import self from '../assets/self.png';
import bg from '../assets/test.png';
import dayjs from 'dayjs';
import { showNotify, showToast, showDialog, Toast } from '@nutui/nutui'
import { CloseLittle } from '@nutui/icons-vue'
import { Search2, Left, Photograph, Message } from '@nutui/icons-vue'

const val = ref('')
const show = ref(false)
const { proxy } = getCurrentInstance()
const isSpinning = ref(false);
const visible = ref(false)

const cardDataBase = ref([])
const scardDataBase = ref([])
const searchval = ref('')

const IgetCardList = async () => {
    let res = await axios.get(`${import.meta.env.VITE_APIURL}/card/list`)
    cardDataBase.value = res.data.data.reverse()
    scardDataBase.value = cardDataBase.value
}
IgetCardList()

const showDetail = (text) => {
    popType.value = 3
    searchval.value = text
    fuzzySearch(searchval.value)
}

const fuzzySearch = (searchTerm) => {
    const regex = new RegExp(searchTerm, 'i'); // 'i' 表示不区分大小写
    scardDataBase.value = cardDataBase.value.filter(item =>
        regex.test(item.title) || regex.test(item.desc)
    );
}

const highlightKeywords = (text, keywords) => {
    if (!keywords) {
        return text
    }
    // 将关键字数组转换为一个正则表达式
    const regex = new RegExp(keywords.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');

    // 使用replace方法替换匹配到的关键字
    return text.replace(regex, (match) => `<span style="background-color: skyblue;padding:2px;border-radius:4px">${match}</span>`);
}
const confirmAddCard = () => {
    proxy.$refs.formRef?.validate().then(({ valid, errors }) => {
        if (valid) {
            // console.log('success:', cardConfig.value)
        } else {
            console.warn('error:', errors)
        }
    })
}

const addCard = async () => {
    let res = await axios.post(`${import.meta.env.VITE_APIURL}/card/add`, cardConfig.value)
    if (res.data.code == 200) {
        confirmResetCard()
        show.value = false
        showToast.success('新增成功！')

    } else {
        confirmAddCard()
    }
}
const confirmResetCard = () => {
    cardConfig.value = {
        cover: null,
        title: null,
        desc: null
    }
    currentCardCoverIndex.value = 0
    cardConfig.value.cover = coverList.value[currentCardCoverIndex.value]
}
const currentCardCoverIndex = ref(0)
watch(() => currentCardCoverIndex.value, (n) => {
    cardConfig.value.cover = coverList.value[currentCardCoverIndex.value]
}, {

})

const cardConfig = ref({
    cover: null,
    title: null,
    desc: null
})
const coverList = ref([])

const IgetCardCoverList = async () => {
    let res = await axios.get(`${import.meta.env.VITE_APIURL}/card/cardCoverList`)
    coverList.value = res.data.data
    cardConfig.value.cover = coverList.value[currentCardCoverIndex.value]
}

// 失去焦点校验
const customBlurValidate = (prop) => {
    // console.log(prop, '22')
    confirmAddCard()
}
// onMounted(() => {
//     proxy.$refs.formRef?.reset()
// })
const navList = ref([
    {
        id: 1,
        text: '规则',
        icon: rule
    },
    {
        id: 2,
        text: '历史',
        icon: his
    },
    {
        id: 3,
        text: '卡库',
        icon: base
    },
    {
        id: 4,
        text: '自定义',
        icon: self
    },
    {
        id: 5,
        text: '认怂书',
        icon: self
    }
])
const popType = ref(-1)


const recordList = ref([])
const IgetRecordList = async () => {
    let res = await axios.get(`${import.meta.env.VITE_APIURL}/card/recordList`)
    recordList.value = res.data.data
}



const tselected = (e) => {
    popType.value = e.item.id



    switch (popType.value) {
        case 2:
            IgetRecordList()


            setTimeout(() => {
                proxy.$refs.box.scrollTop = proxy.$refs.box.scrollHeight
            }, 400);

            break;
        case 3:
            IgetCardList()
            break;

        case 4:

            IgetCardCoverList()
            break;

        default:
            break;
    }
    visible.value = false
    show.value = true
}
const spinningText = ref('开始抽牌');
const prizeResult = ref('');
// '特等奖'
const prizes = ['小牛奖', '小哈奖', '大牛奖', '大哈奖', '老头乐奖', '旺旺奖', '坚果奖'];

const ysprizes = ['小牛奖', '小哈奖', '大牛奖', '大哈奖', '老头乐奖', '旺旺奖', '坚果奖', '三等奖', '二等奖'];

const wzprizes = ['小牛奖', '小哈奖', '大牛奖', '大哈奖', '老头乐奖', '旺旺奖', '坚果奖', '三等奖', '二等奖', '一等奖', '特等奖'];

const cCard = ref({})
const delCard = (id) => {

    showDialog({
        overlayStyle: { background: 'rgba(0,0,0,0)' },
        title: '温馨提示',
        content: '是否删除此卡牌',
        overlayStyle: {
            position: "absolute",
            zIndex: 99999
        },
        teleport: 'body',
        popStyle: {
            position: "absolute",
            zIndex: 99999
        },
        onOk: async() => {
            try {
            let res= await axios.delete(`${import.meta.env.VITE_APIURL}/card/del?id=${id}`)
            if(res){
                showToast.success('删除成功')

                IgetCardList()
            }
            } catch (error) {
                console.log(error)
            }
        }
    })
}
const spin = () => {
    if (isSpinning.value) {
        return console.log('busy')
    } else {
        console.log('normal')
    }

    isSpinning.value = true;

    spinningText.value = '正在获取海克斯...';
    setTimeout(async () => {
        isSpinning.value = false;
        const randomNumber = Math.floor(Math.random() * cardDataBase.value.length);
        cCard.value = cardDataBase.value[randomNumber]

        // console.log(cCard.value, 'cCard.value')

        prizeResult.value = cCard.value._id

        try {
            await axios.post(`${import.meta.env.VITE_APIURL}/card/addRecord`, { id: cCard.value._id, cardName: cCard.value.title })
        } catch (error) {
            console.log(error)
        }



        spinningText.value = '开始抽牌';
    }, 3000);




};

</script>

<style lang="scss" scoped>
:deep(.nut-fixed-nav__btn) {
    // width: 60px;
    // height: 30px;
    background-color: skyblue !important;
}

:deep(.nut-fixed-nav__list) {
    // width: 60px;
    // height: 30px;
}

.lottery-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100vh;
    background: url('../assets/sparkles.gif') no-repeat;
    background-size: 100% 100%;
}

.prize {
    font-size: 2rem;
    padding: 1rem;
    border: 1px solid #ccc;
    border-radius: 8px;
    margin-bottom: 1rem;
}

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.5s;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}


.text {
    background-color: #6c5ce7;
    padding: 10px 20px;
    width: 100%;
    height: 18px;
    display: flex;
    margin-bottom: 10px;
    align-items: center;
    justify-content: center;
    font-size: 16px;

    font-weight: 700;
    color: #fff;
    border-radius: 5px;
    transition: all ease 0.1s;
    box-shadow: 0px 5px 0px 0px #a29bfe;
}



.button {
    cursor: pointer;
    font-size: large;
    font-family: inherit;
    font-weight: bold;
    color: #0011ff;
    background-color: #f8f8fd;
    padding: 0.8em 2.2em;
    border-radius: 50em;
    border: 6px solid #8b93f8;

    box-shadow: 0px 8px #1f35ff;
}

.button:active {
    position: relative;
    top: 8px;
    border: 6px solid #646fff;
    box-shadow: 0px 0px;
}


.card {
    overflow: visible;
    width: 290px;
    height: 454px;
    /* border: 1px solid red; */
    border-radius: 6px;
    position: relative;
    z-index: 99;
}

.content {
    width: 100%;
    height: 100%;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    transform: perspective(1000px);
    -webkit-transform: perspective(1000px);
    transition: transform ease-in-out 300ms;
    box-shadow: 0px 0px 10px 1px #000000ee;
    border-radius: 5px;
}

.front,
.back {
    background-color: #151515;
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    z-index: 9;
    border-radius: 5px;
    overflow: hidden;
}

.back {
    width: 100%;
    height: 100%;
    justify-content: center;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.back::before {
    position: absolute;
    content: ' ';
    display: block;
    width: 160px;
    height: 160%;
    background: linear-gradient(90deg, transparent, #e385fc, #e385fc, #e385fc, #e385fc, transparent);
    animation: rotation_481 5000ms infinite linear;
}

.back-content {
    position: absolute;
    width: 99%;
    height: 99%;
    background-color: #151515;
    border-radius: 5px;
    color: white;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    /* gap: 30px; */
}

.card:hover .content {
    transform: rotateY(180deg);
}

@keyframes rotation_481 {
    0% {
        transform: rotateZ(0deg);
    }

    0% {
        transform: rotateZ(360deg);
    }
}

.front {
    transform: rotateY(180deg);
    color: white;
    background: url('../assets/test.png') no-repeat;
    background-size: 100% 100%;
    font-weight: 600;
    color: white;
}

.front .front-content {
    position: absolute;
    width: 100%;
    height: 100%;
    padding: 10px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.front-content .badge {
    background-color: #00000055;
    padding: 2px 10px;
    border-radius: 10px;
    backdrop-filter: blur(2px);
    width: fit-content;
}

.description {
    box-shadow: 0px 0px 10px 5px #00000088;
    width: 100%;
    padding: 10px;
    background-color: #00000099;
    backdrop-filter: blur(5px);
    border-radius: 5px;
}

.title {
    font-size: 11px;
    max-width: 100%;
    display: flex;
    justify-content: space-between;
}

.title p {
    width: 50%;
}

.card-footer {
    color: #ffffff88;
    margin-top: 5px;
    font-size: 8px;
}

.front .img {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.circle {
    /* width: 90px;
    height: 90px; */
    border-radius: 50%;

    position: relative;
    filter: blur(1px);
    animation: floating 2600ms infinite linear;
}

#left {
    background: url('../assets/hex.png') no-repeat;
    background-size: 100% 100%;
    left: -60px;
    top: 60px;
    border-radius: 50%;
    width: 70px;
    height: 70px;
    animation-delay: -800ms;
}

#bottom {
    background: url('../assets/hex2.png') no-repeat;
    left: -80px;
    background-size: 100% 100%;
    top: -120px;
    border-radius: 50%;
    width: 80px;
    height: 80px;
    animation-delay: -800ms;
}

#top {
    background: url('../assets/hex3.png') no-repeat;
    background-size: 100% 100%;
    left: -40px;
    border-radius: 50%;
    top: -40px;
    width: 100px;
    height: 100px;
    animation-delay: -800ms;
}

#right {
    background: url('../assets/hex4.png') no-repeat;
    background-size: 100% 100%;
    left: 70px;
    border-radius: 50%;
    top: 10px;
    width: 120px;
    height: 120px;
    animation-delay: -1800ms;
}

#bottom {
    background: url('../assets/hex2.png') no-repeat;
    left: 60px;
    background-size: 100% 100%;
    top: -70px;
    border-radius: 50%;
    width: 140px;
    height: 140px;
    animation-delay: -800ms;
}



@keyframes floating {
    0% {
        transform: translateY(0px);
    }

    50% {
        transform: translateY(10px);
    }

    100% {
        transform: translateY(0px);
    }
}





.loader {
    --duration: 3s;
    --primary: rgba(39, 94, 254, 1);
    --primary-light: #2f71ff;
    --primary-rgba: rgba(39, 94, 254, 0);
    width: 200px;
    height: 320px;
    position: relative;
    transform-style: preserve-3d;
}

@media (max-width: 480px) {
    .loader {
        zoom: 0.44;
    }
}

.loader:before,
.loader:after {
    --r: 20.5deg;
    content: "";
    width: 320px;
    height: 140px;
    position: absolute;
    right: 32%;
    bottom: -11px;
    /* change the back groung color on switching from light to dark mood */
    background: url('../assets/sparkles.gif');
    transform: translateZ(200px) rotate(var(--r));
    -webkit-animation: mask var(--duration) linear forwards infinite;
    animation: mask var(--duration) linear forwards infinite;
}

.loader:after {
    --r: -20.5deg;
    right: auto;
    left: 32%;
}

.loader .ground {
    position: absolute;
    left: -50px;
    bottom: -120px;
    transform-style: preserve-3d;
    transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
}

.loader .ground div {
    transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
    width: 200px;
    height: 200px;
    background: var(--primary);
    background: linear-gradient(45deg, var(--primary) 0%, var(--primary) 50%, var(--primary-light) 50%, var(--primary-light) 100%);
    transform-style: preserve-3d;
    -webkit-animation: ground var(--duration) linear forwards infinite;
    animation: ground var(--duration) linear forwards infinite;
}

.loader .ground div:before,
.loader .ground div:after {
    --rx: 90deg;
    --ry: 0deg;
    --x: 44px;
    --y: 162px;
    --z: -50px;
    content: "";
    width: 156px;
    height: 300px;
    opacity: 0;
    background: linear-gradient(var(--primary), var(--primary-rgba));
    position: absolute;
    transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
    -webkit-animation: ground-shine var(--duration) linear forwards infinite;
    animation: ground-shine var(--duration) linear forwards infinite;
}

.loader .ground div:after {
    --rx: 90deg;
    --ry: 90deg;
    --x: 0;
    --y: 177px;
    --z: 150px;
}

.loader .box {
    --x: 0;
    --y: 0;
    position: absolute;
    -webkit-animation: var(--duration) linear forwards infinite;
    animation: var(--duration) linear forwards infinite;
    transform: translate(var(--x), var(--y));
}

.loader .box div {
    background-color: var(--primary);
    width: 48px;
    height: 48px;
    position: relative;
    transform-style: preserve-3d;
    -webkit-animation: var(--duration) ease forwards infinite;
    animation: var(--duration) ease forwards infinite;
    transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
}

.loader .box div:before,
.loader .box div:after {
    --rx: 90deg;
    --ry: 0deg;
    --z: 24px;
    --y: -24px;
    --x: 0;
    content: "";
    position: absolute;
    background-color: inherit;
    width: inherit;
    height: inherit;
    transform: rotateX(var(--rx)) rotateY(var(--ry)) translate(var(--x), var(--y)) translateZ(var(--z));
    filter: brightness(var(--b, 1.2));
}

.loader .box div:after {
    --rx: 0deg;
    --ry: 90deg;
    --x: 24px;
    --y: 0;
    --b: 1.4;
}

.loader .box.box0 {
    --x: -220px;
    --y: -120px;
    left: 58px;
    top: 108px;
}

.loader .box.box1 {
    --x: -260px;
    --y: 120px;
    left: 25px;
    top: 120px;
}

.loader .box.box2 {
    --x: 120px;
    --y: -190px;
    left: 58px;
    top: 64px;
}

.loader .box.box3 {
    --x: 280px;
    --y: -40px;
    left: 91px;
    top: 120px;
}

.loader .box.box4 {
    --x: 60px;
    --y: 200px;
    left: 58px;
    top: 132px;
}

.loader .box.box5 {
    --x: -220px;
    --y: -120px;
    left: 25px;
    top: 76px;
}

.loader .box.box6 {
    --x: -260px;
    --y: 120px;
    left: 91px;
    top: 76px;
}

.loader .box.box7 {
    --x: -240px;
    --y: 200px;
    left: 58px;
    top: 87px;
}

.loader .box0 {
    -webkit-animation-name: box-move0;
    animation-name: box-move0;
}

.loader .box0 div {
    -webkit-animation-name: box-scale0;
    animation-name: box-scale0;
}

.loader .box1 {
    -webkit-animation-name: box-move1;
    animation-name: box-move1;
}

.loader .box1 div {
    -webkit-animation-name: box-scale1;
    animation-name: box-scale1;
}

.loader .box2 {
    -webkit-animation-name: box-move2;
    animation-name: box-move2;
}

.loader .box2 div {
    -webkit-animation-name: box-scale2;
    animation-name: box-scale2;
}

.loader .box3 {
    -webkit-animation-name: box-move3;
    animation-name: box-move3;
}

.loader .box3 div {
    -webkit-animation-name: box-scale3;
    animation-name: box-scale3;
}

.loader .box4 {
    -webkit-animation-name: box-move4;
    animation-name: box-move4;
}

.loader .box4 div {
    -webkit-animation-name: box-scale4;
    animation-name: box-scale4;
}

.loader .box5 {
    -webkit-animation-name: box-move5;
    animation-name: box-move5;
}

.loader .box5 div {
    -webkit-animation-name: box-scale5;
    animation-name: box-scale5;
}

.loader .box6 {
    -webkit-animation-name: box-move6;
    animation-name: box-move6;
}

.loader .box6 div {
    -webkit-animation-name: box-scale6;
    animation-name: box-scale6;
}

.loader .box7 {
    -webkit-animation-name: box-move7;
    animation-name: box-move7;
}

.loader .box7 div {
    -webkit-animation-name: box-scale7;
    animation-name: box-scale7;
}

@-webkit-keyframes box-move0 {
    12% {
        transform: translate(var(--x), var(--y));
    }

    25%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move0 {
    12% {
        transform: translate(var(--x), var(--y));
    }

    25%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale0 {
    6% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    14%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale0 {
    6% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    14%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move1 {
    16% {
        transform: translate(var(--x), var(--y));
    }

    29%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move1 {
    16% {
        transform: translate(var(--x), var(--y));
    }

    29%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale1 {
    10% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    18%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale1 {
    10% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    18%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move2 {
    20% {
        transform: translate(var(--x), var(--y));
    }

    33%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move2 {
    20% {
        transform: translate(var(--x), var(--y));
    }

    33%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale2 {
    14% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    22%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale2 {
    14% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    22%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move3 {
    24% {
        transform: translate(var(--x), var(--y));
    }

    37%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move3 {
    24% {
        transform: translate(var(--x), var(--y));
    }

    37%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale3 {
    18% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    26%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale3 {
    18% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    26%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move4 {
    28% {
        transform: translate(var(--x), var(--y));
    }

    41%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move4 {
    28% {
        transform: translate(var(--x), var(--y));
    }

    41%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale4 {
    22% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    30%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale4 {
    22% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    30%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move5 {
    32% {
        transform: translate(var(--x), var(--y));
    }

    45%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move5 {
    32% {
        transform: translate(var(--x), var(--y));
    }

    45%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale5 {
    26% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    34%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale5 {
    26% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    34%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move6 {
    36% {
        transform: translate(var(--x), var(--y));
    }

    49%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move6 {
    36% {
        transform: translate(var(--x), var(--y));
    }

    49%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale6 {
    30% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    38%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale6 {
    30% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    38%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes box-move7 {
    40% {
        transform: translate(var(--x), var(--y));
    }

    53%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@keyframes box-move7 {
    40% {
        transform: translate(var(--x), var(--y));
    }

    53%,
    52% {
        transform: translate(0, 0);
    }

    80% {
        transform: translate(0, -32px);
    }

    90%,
    100% {
        transform: translate(0, 188px);
    }
}

@-webkit-keyframes box-scale7 {
    34% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    42%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@keyframes box-scale7 {
    34% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(0);
    }

    42%,
    100% {
        transform: rotateY(-47deg) rotateX(-15deg) rotateZ(15deg) scale(1);
    }
}

@-webkit-keyframes ground {

    0%,
    65% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
    }

    75%,
    90% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(1);
    }

    100% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
    }
}

@keyframes ground {

    0%,
    65% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
    }

    75%,
    90% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(1);
    }

    100% {
        transform: rotateX(90deg) rotateY(0deg) translate(-48px, -120px) translateZ(100px) scale(0);
    }
}

@-webkit-keyframes ground-shine {

    0%,
    70% {
        opacity: 0;
    }

    75%,
    87% {
        opacity: 0.2;
    }

    100% {
        opacity: 0;
    }
}

@keyframes ground-shine {

    0%,
    70% {
        opacity: 0;
    }

    75%,
    87% {
        opacity: 0.2;
    }

    100% {
        opacity: 0;
    }
}

@-webkit-keyframes mask {

    0%,
    65% {
        opacity: 0;
    }

    66%,
    100% {
        opacity: 1;
    }
}

@keyframes mask {

    0%,
    65% {
        opacity: 0;
    }

    66%,
    100% {
        opacity: 1;
    }
}
</style>